using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Collections.ObjectModel;
using Microsoft.Practices.ServiceLocation;

namespace Sogeti.Guidelines.WCF.Hosting
{
    public class CommonServiceHostServiceBehavior : IServiceBehavior
    {
        public CommonServiceHostInstanceProvider InstanceProvider { get; set; }

        private ServiceHost _serviceHost;

        public CommonServiceHostServiceBehavior()
        {
            InstanceProvider = new CommonServiceHostInstanceProvider();
        }


        public CommonServiceHostServiceBehavior(IServiceLocator serviceLocator)
        {
            InstanceProvider = new CommonServiceHostInstanceProvider {Container = serviceLocator};
        }


        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (var endpoint in serviceHostBase.ChannelDispatchers
                .OfType<ChannelDispatcher>()
                .SelectMany(cd => cd.Endpoints))
            {
                InstanceProvider.ServiceType = serviceDescription.ServiceType;
                endpoint.DispatchRuntime.InstanceProvider = InstanceProvider;
            }
        }


        public void AddBindingParameters(
            ServiceDescription serviceDescription,
            ServiceHostBase serviceHostBase,
            Collection<ServiceEndpoint> endpoints,
            BindingParameterCollection bindingParameters)
        {
        }


        public void Validate(
            ServiceDescription serviceDescription,
            ServiceHostBase serviceHostBase)
        {
        }


        public void AddToHost(ServiceHost host)
        {
            if (_serviceHost != null)
                return;

            host.Description.Behaviors.Add(this);

            _serviceHost = host;
        }
    }
}